#include "subscription.h"


ISubscription* CreateSubscription(int id,int topic,unsigned int addr)
{
	return new Subscription(id,topic,addr);
}

void FreeSubscription(ISubscription* sub)
{
	delete sub;
}

bool Subscription::AddValue(int key,MsgExpress::DataType type,std::string value,MsgExpress::Operator oper)
{
	ValueData* valueData=mapKeyValues[key];
	if(!valueData)
	{
		valueData=new ValueData();
		mapKeyValues[key]=valueData;
		valueData->type=type;
	}
	else
	{
		if(valueData->type!=type)
			return false;
	}
	OperValue* operValue=new OperValue();
	operValue->oper=oper;
	operValue->value=value;
	valueData->vecValues.push_back(operValue);
	return true;
}

bool Subscription::AddString(int key,std::string value,MsgExpress::Operator oper)
{
	return AddValue(key,MsgExpress::STRING,value,oper);
}
bool Subscription::AddRaw(int key,const char * str,size_t size,MsgExpress::Operator oper)
{
	return AddValue(key,MsgExpress::BINARY,string(str,size),oper);
}
#define ADDVALUE(key,type,value,oper) \
	std::string str; \
	str.resize(sizeof(value)); \
	memcpy((void*)(str.data()),&value,str.size()); \
	return AddValue(key,type,str,oper); 

bool Subscription::AddInt32(int key,int value,MsgExpress::Operator oper)
{
	value=htonl(value);
	ADDVALUE(key,MsgExpress::INT32,value,oper);
}

bool Subscription::AddUInt32(int key,unsigned int value,MsgExpress::Operator oper)
{
	value=htonl(value);
	ADDVALUE(key,MsgExpress::UINT32,value,oper);
}
bool Subscription::AddInt64(int key,int64_t value,MsgExpress::Operator oper)
{
	value=htonll(value);
	ADDVALUE(key,MsgExpress::INT64,value,oper)
}
bool Subscription::AddUInt64(int key,uint64_t value,MsgExpress::Operator oper)
{
	value=htonll(value);
	ADDVALUE(key,MsgExpress::UINT64,value,oper)
}
bool Subscription::AddFloat(int key,float value,MsgExpress::Operator oper)
{
	ADDVALUE(key,MsgExpress::FLOAT,value,oper)
}
bool Subscription::AddDouble(int key,double value,MsgExpress::Operator oper)
{
	ADDVALUE(key,MsgExpress::DOUBLE,value,oper)
}
bool Subscription::AddDatetime(int key,time_t value,MsgExpress::Operator oper)
{
	value=htonll(value);
	ADDVALUE(key,MsgExpress::DATETIME,value,oper)
}

void Subscription::AddIndex(int index)
{
	mIndex.push_back(index);
}

void Subscription::GetSubData(MsgExpress::SubscribeData& sub)
{
	sub.set_subid(mId);
	sub.set_topic(mTopic);
	sub.set_useraddr(mAddr);
	std::vector<int>::iterator it=mIndex.begin();
	while(it!=mIndex.end())
	{
		sub.add_index(*it);
		it++;
	}

	std::map<int,ValueData*>::iterator iter=mapKeyValues.begin();
	while(iter!=mapKeyValues.end())
	{
		int key=iter->first;
		ValueData* valueData=iter->second;
		MsgExpress::DataType type=valueData->type;
		MsgExpress::DataItem* item=0;
		
		std::vector<OperValue*>::iterator it=valueData->vecValues.begin();
		while(it!=valueData->vecValues.end())
		{
			if(MsgExpress::Equal==(*it)->oper)
			{
				if(!item)
				{
				    item=sub.add_condition();
				    item->set_key(key);
					//item->set_type(type);
				}
				//item->add_value((*it)->value);
			}
			else
			{
				MsgExpress::ConditionItem* conItem=sub.add_excondition();
				conItem->set_key(key);
				conItem->set_type(type);
				MsgExpress::ConditionValue* conValue=conItem->add_value();
				conValue->set_value((*it)->value);
				conValue->set_operator_((*it)->oper);
			}
			it++;
		}
		iter++;
	}
}

Subscription::Subscription(int id,int topic,unsigned int addr)
{
	mId=id;
	mTopic=topic;
	mAddr=addr;
}

Subscription::~Subscription()
{
	std::map<int,ValueData*>::iterator it=mapKeyValues.begin();
	while(it!=mapKeyValues.end())
	{
		delete it->second;
		it++;
	}
	mapKeyValues.clear();
}
